#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int input_fd, output_fd;
    char *input_data, *output_data, *input_file_name;
    char output_file_name[256];
    struct stat sbuf;

    input_file_name = argv[1];
    strcpy (output_file_name, input_file_name);
    strcat (output_file_name, "-copy");

    if (argc != 2) {
        fprintf(stderr, "usage: mmap <input filename>\n");
        exit(1);
    }

    if ((input_fd = open(input_file_name, O_RDONLY)) == -1) {
        perror("open input file");
        exit(1);
    }

    if ((output_fd = open(output_file_name, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR)) == -1) {
        perror("open output file");
        exit(1);
    }

    if (stat(input_file_name, &sbuf) == -1) {
        perror("stat");
        exit(1);
    }
    
    if (ftruncate(output_fd, sbuf.st_size) == -1) {
        perror("couldn't truncate");
        exit(1);
    }

    input_data = mmap((caddr_t)0, sbuf.st_size, PROT_READ, MAP_SHARED, input_fd, 0); 
    if (input_data == (caddr_t)(-1)) {
        perror("mmap");
        exit(1);
    }

    output_data = mmap((caddr_t)0, sbuf.st_size, PROT_WRITE, MAP_SHARED, output_fd, 0);
    if (output_data == (caddr_t)(-1)) {
        perror("mmap");
        exit(1);
    }

    memcpy(output_data, input_data, sbuf.st_size);
    munmap(output_data, sbuf.st_size);
    
    if ((close(input_fd)) == -1) {
        perror("close input file");
        exit(1);
    }

    if ((close(output_fd)) == -1) {
        perror("close output file");
        exit(1);
    }

    return 0;
}
